﻿using System;
using System.Globalization;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;

namespace SilverlightUtils
{
	public class ComboListItem
	{
		public string DisplayName;
		public ulong ItemId;

		public override string ToString()
		{
			return DisplayName;
		}
	}

	public class NumberTypeToStringConverter : IValueConverter
	{
		#region IValueConverter Members

		public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
		{
			if (value == null)
			{
				throw new NullReferenceException();
			}

			return value.ToString();
		}

		public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
		{
			MethodInfo methodInfo = targetType.GetMethod("Parse");

			if (methodInfo == null)
			{
				throw new MissingMethodException("The targetType to convert back to a Number must implement a Parse method");
			}

			return methodInfo.Invoke(null, new[] {value});
		}

		#endregion
	}

	public class DateTimeToStringConverter : IValueConverter
	{
		#region IValueConverter Members

		public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
		{
			if (!(value is DateTime))
				return "Invalid data";
			return ((DateTime) value).ToString("yyyy/MM/dd HH:mm:ss");
		}

		public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
		{
			if (value is string)
			{
				DateTime retval;
				if (DateTime.TryParse((string) value, out retval))
					return retval;
			}
			return new DateTime();
		}

		#endregion
	}
}

namespace System
{
	public sealed class Stopwatch
	{
		private long _elapsed;
		private bool _isRunning;
		private long _startTick;

		public bool IsRunning
		{
			get { return _isRunning; }
		}

		public TimeSpan Elapsed
		{
			get { return TimeSpan.FromMilliseconds(ElapsedMilliseconds); }
		}

		public long ElapsedMilliseconds
		{
			get { return GetCurrentElapsedTicks()/TimeSpan.TicksPerMillisecond; }
		}

		public long ElapsedTicks
		{
			get { return GetCurrentElapsedTicks(); }
		}

		public static Stopwatch StartNew()
		{
			Stopwatch sw = new Stopwatch();
			sw.Start();
			return sw;
		}

		public void Reset()
		{
			_elapsed = 0;
			_isRunning = false;
			_startTick = 0;
		}

		public void Start()
		{
			if (!_isRunning)
			{
				_startTick = GetCurrentTicks();
				_isRunning = true;
			}
		}

		public void Stop()
		{
			if (_isRunning)
			{
				_elapsed += GetCurrentTicks() - _startTick;
				_isRunning = false;
			}
		}

		private long GetCurrentElapsedTicks()
		{
			return (_elapsed + (IsRunning ? (GetCurrentTicks() - _startTick) : 0));
		}

		private static long GetCurrentTicks()
		{
			// TickCount: Gets the number of milliseconds elapsed since the system started.
			return Environment.TickCount*TimeSpan.TicksPerMillisecond;
		}
	}

	public static class Extensions
	{
		public static void SetClip(this FrameworkElement element)
		{
			element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
			element.Clip = new RectangleGeometry
			{
				Rect = new Rect
					(
					0, 0,
					element.ActualWidth,
					element.ActualHeight
					)
			};
		}

		public static string EncryptPassword(this string s)
		{
			SHA256Managed sha = new SHA256Managed();
			sha.Initialize();
			RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
			byte[] salt = new byte[new Random(Environment.TickCount).Next(16, 64)];
			random.GetBytes(salt);

			byte[] input = Encoding.UTF8.GetBytes(s);
			byte[] hashed = sha.ComputeHash(input);
			string output = Convert.ToBase64String(hashed);
			return output;
		}

		public static ulong ToLong(this Guid id)
		{
			return BitConverter.ToUInt64(id.ToByteArray(), 8);
			//byte[] all = id.ToByteArray();
			//byte[] sig = all.ToList().GetRange(8, 8).ToArray();
			//Db4oUUID output = new Db4oUUID(BitConverter.ToInt64(all, 0), sig);
			//return output;
		}
	}
}